package com.vito.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.vito.config.AppConfig;
import com.vito.framework.base.model.FileBean;
import com.vito.util.oss.COSUtil;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UploadUtil {

    private UploadUtil() {
    }

    /**
     * 上传图片<br/>
     * 图片会被上传至用户上下文的attacment文件夹的subFolder子文件夹中<br/>
     *
     * @param MultipartFile SpringMVC 图片file对象
     * @param fileFileName  上传的图片原名
     * @param subFolder     子文件夹名
     * @return
     * @since 上传后的本地路径，如:fs:/attachment/goods/2001010101030.jpg<br/>
     */
    public static FileBean upload(MultipartFile file, String fileFileName, String subFolder) {
        FileBean fileBean = new FileBean();
        if (file == null || fileFileName == null) throw new IllegalArgumentException("file or filename object is null");
        if (subFolder == null) throw new IllegalArgumentException("subFolder is null");

        if (!FileUtil.isAllowUp(fileFileName)) throw new IllegalArgumentException("不被允许的上传文件类型");

        String fileName = null;
        String filePath = "";
        Long fileSize = file.getSize();
        String ext = FileUtil.getFileExt(fileFileName);
        fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomString(4) + "." + ext;

        filePath = AppConfig.SOURCE_PUBLIC_PATH + "/" + AppConfig.ATTACHMENT_DIR + "/";
        if (subFolder != null) {
            filePath += subFolder + "/";
        }

        filePath = filePath.replace("//", "/");
        filePath += fileName;
        try {
            FileUtil.createFile(file.getInputStream(), filePath);
            File f = new File(filePath);
            String cosPath = filePath.replace(AppConfig.SOURCE_PUBLIC_PATH, "");
            COSUtil.upload(f, AppConfig.OSS_DEFAULT_BUCKET, cosPath);
            FileUtil.delete(filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        filePath = filePath.replace(AppConfig.SOURCE_PUBLIC_PATH, AppConfig.FILE_STORE_PREFIX);
        fileBean.setFileName(fileName);
        fileBean.setFileType(ext);
        fileBean.setFileUrl(UploadUtil.replacePath(filePath));
        fileBean.setFilePath(filePath);
        fileBean.setFileSize(fileSize);
        return fileBean;
    }

    /**
     * 上传文件<br/>
     * 上传至用户上下文的attacment文件夹的subFolder子文件夹中<br/>
     *
     * @param inputStream  文件输入流
     * @param fileFileName 上传的图片原名
     * @param subFolder    子文件夹名
     * @return fileName fileType path
     * @since 上传后的本地路径，如:fs:/attachment/goods/2001010101030.jpg<br/>
     */
    public static FileBean upload(InputStream inputStream, String fileExt, String subFolder) {
        FileBean fileBean = new FileBean();
        if (inputStream == null) throw new IllegalArgumentException("file or filename object is null");
        if (subFolder == null) throw new IllegalArgumentException("subFolder is null");

        if (!FileUtil.isAllowUp(fileExt)) throw new IllegalArgumentException("不被允许的上传文件类型");

        String fileName = null;
        String filePath = "";
        fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomString(4) + fileExt;

        filePath = AppConfig.SOURCE_PUBLIC_PATH + "/" + AppConfig.ATTACHMENT_DIR + "/";
        if (subFolder != null) {
            filePath += subFolder + "/";
        }
        filePath = filePath.replace("//", "/");
        filePath += fileName;

        FileUtil.createFile(inputStream, filePath);
        File f = new File(filePath);
        Long fileSize = f.length();
        String cosPath = filePath.replace(AppConfig.SOURCE_PUBLIC_PATH, "");
        COSUtil.upload(f, AppConfig.OSS_DEFAULT_BUCKET, cosPath);
        FileUtil.delete(filePath);
        filePath = filePath.replace(AppConfig.SOURCE_PUBLIC_PATH, AppConfig.FILE_STORE_PREFIX);
        fileBean.setFileName(fileName);
        fileBean.setFileType(fileExt);
        fileBean.setFileUrl(UploadUtil.replacePath(filePath));
        fileBean.setFilePath(filePath);
        fileBean.setFileSize(fileSize);
        return fileBean;
    }

    public static FileBean upload(String filePath, String subFolder) {
        File file = new File(filePath);
        return upload(file, subFolder);
    }

    /**
     * 上传图片<br/>
     * 图片会被上传至用户上下文的attacment文件夹的subFolder子文件夹中<br/>
     *
     * @param file         图片file对象
     * @param fileFileName 上传的图片原名
     * @param subFolder    子文件夹名
     * @return
     * @since 上传后的本地路径，如:fs:/attachment/goods/2001010101030.jpg<br/>
     */
    public static FileBean upload(File file, String subFolder) {
        FileBean fileBean = new FileBean();

        if (file == null) throw new IllegalArgumentException("file or filename object is null");
        if (subFolder == null) throw new IllegalArgumentException("subFolder is null");
        String fileFileName = file.getName();
        if (!FileUtil.isAllowUp(fileFileName)) throw new IllegalArgumentException("不被允许的上传文件类型");

        String ext = FileUtil.getFileExt(fileFileName);
        String fileName = null;
        String filePath = "";
        Long fileSize = file.length();

        fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomString(4) + "." + ext;

        filePath = AppConfig.SOURCE_PUBLIC_PATH + "/" + AppConfig.ATTACHMENT_DIR + "/";
        if (subFolder != null) {
            filePath += subFolder + "/";
        }

        filePath = filePath.replace("//", "/");
        filePath += fileName;
        FileUtil.createFile(file, filePath);
        File f = new File(filePath);
        String cosPath = filePath.replace(AppConfig.SOURCE_PUBLIC_PATH, "");
        COSUtil.upload(f, AppConfig.OSS_DEFAULT_BUCKET, cosPath);
        FileUtil.delete(filePath);
        filePath = filePath.replace(AppConfig.SOURCE_PUBLIC_PATH, AppConfig.FILE_STORE_PREFIX);

        fileBean.setFileName(fileName);
        fileBean.setFileType(ext);
        fileBean.setFileUrl(UploadUtil.replacePath(filePath));
        fileBean.setFilePath(filePath);
        fileBean.setFileSize(fileSize);
        return fileBean;
    }

    /**
     * 替换文件<br/>
     * 将原文件替换<br/>
     *
     * @param file     新文件 对象
     * @param fileName 原文件位置
     */
    public static void replace(File file, String fileName) {
        if (file == null || fileName == null) throw new IllegalArgumentException("file or filename object is null");
        if (!FileUtil.isAllowUp(fileName)) throw new IllegalArgumentException("不被允许的上传文件类型");

        fileName = replaceFilePath(fileName);
        deleteFile(fileName);
        FileUtil.createFile(file, fileName);
    }

    public static String replaceFilePath(String path) {
        if (StrUtil.isEmpty(path)) return path;
        return path.replaceAll(AppConfig.FILE_STORE_PREFIX, AppConfig.SOURCE_PUBLIC_PATH);
    }

    public static String replacePath(String path) {
        if (StrUtil.isEmpty(path)) return path;
        return path.replaceAll(AppConfig.FILE_STORE_PREFIX, AppConfig.SOURCE_SERVER_DOMAIN);
    }

    /**
     * 删除某个上传的文件
     *
     * @param filePath 文件全路径如：http://static.eop.com/user/1/1/attachment/goods/2001010101030.jpg
     */
    public static void deleteFile(String filePath) {
        String cosPath = filePath.replace(AppConfig.FILE_STORE_PREFIX, "");
        filePath = replacePath(filePath);
        filePath = filePath.replaceAll(AppConfig.SOURCE_SERVER_DOMAIN, AppConfig.SOURCE_PUBLIC_PATH);
        FileUtil.delete(filePath);
        COSUtil.delete(cosPath, AppConfig.OSS_DEFAULT_BUCKET);
    }

    /**
     * 删除某个上传的文件
     *
     * @param filePath 文件全路径如：http://static.eop.com/user/1/1/attachment/goods/2001010101030.jpg
     */
    public static void deleteFileAndThumb(String filePath) {
        filePath = filePath.replaceAll(AppConfig.SOURCE_SERVER_DOMAIN, AppConfig.SOURCE_PUBLIC_PATH);
        FileUtil.delete(filePath);
        FileUtil.delete(getThumbPath(filePath, "_thumbnail"));
    }

    /**
     * 转换图片的名称
     *
     * @param filePath  如：http://static.eop.com/user/1/1/attachment/goods/2001010101030.jpg
     * @param shortName
     * @return
     */
    public static String getThumbPath(String filePath, String shortName) {
        String pattern = "(.*)([\\.])(.*)";
        String thumbPath = "$1" + shortName + "$2$3";
        Pattern p = Pattern.compile(pattern, 2 | Pattern.DOTALL);
        Matcher m = p.matcher(filePath);
        if (m.find()) {
            String s = m.replaceAll(thumbPath);
            return s;
        }
        return null;
    }
}